home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 38
/
Amiga Format CD38 (1999-03-15)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-04].iso
/
-seriously_amiga-
/
archivers
/
lzhutils_src
/
span.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-01-25
|
5KB
|
234 lines
#define VERSION "2.0"
#define BUFFSIZE 512 /* Fragment size unit */
/* #define PC */
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#ifdef PC
#include <conio.h>
#endif
enum EXIT_VALUE { SUCCESS, ERROR, ABORT };
enum CONDITION { MUST, NEEDNT };
void usage(void);
void span(char *infname, char *outfname, char *lastoutfname, char *outfext);
void bind(char *infname, char *outfname, char *lastinfname, char *infext);
void askdisk(char *type);
void incrdisk(char *ext);
char opensource(char *name, char condition);
char opentarget(char *name);
void readsource(unsigned bytes);
char writetarget(unsigned bytes, char condition);
#define minimum(a, b) (a < b ? a : b)
unsigned char buff[BUFFSIZE];
int infh, outfh;
long infbytesleft;
short disk = 0;
void usage(void)
{
printf("Usage:\n"
" span -s [source file] [target path]\n"
" span -b [target file] [source path]\n\n"
"Examples:\n"
" span -s c:/temp/dummy.zip a:/\n"
" span -b c:/temp/dummy.zip a:/\n");
exit(ERROR);
}
int main(int argc, char **argv)
{
char name[FILENAME_MAX], lastname[FILENAME_MAX], *basename, spanit = 0;
int extpos;
#ifdef PC
char *tmp;
#endif
printf("Span v%s. Copyright (c) 1996-1997 Konstantinos Tampouris, "
"Infinity Labs.\n\n", VERSION);
#ifdef PC
if (!_USE_LFN)
{
printf("No long filename support found\n");
return(ERROR);
}
#endif
if (argc != 4) usage();
if (!stricmp(argv[1], "-s"))
spanit = 1;
else if (stricmp(argv[1], "-b"))
usage();
#ifdef PC
if ((basename = strrchr(argv[2], '/')) < (tmp = strrchr(argv[2], '\\')))
basename = tmp;
if (basename)
#else
if (basename = strrchr(argv[2], '/'))
#endif
basename++;
else
basename = argv[2];
extpos = strlen(basename) + strlen(argv[3]) + 1;
if (extpos + 4 > FILENAME_MAX)
{
printf("%s file name too big\n", (spanit ? "Targer" : "Source"));
return(ERROR);
}
sprintf(name, "%s%s.000", argv[3], basename);
sprintf(lastname, "%s%s.end", argv[3], basename);
if (spanit)
span(argv[2], name, lastname, &name[extpos]);
else
bind(name, argv[2], lastname, &name[extpos]);
return SUCCESS;
}
void span(char *infname, char *outfname, char *lastoutfname, char *outfext)
{
unsigned bytes = 0;
long outfsize;
if (!opensource(infname, MUST)) exit(ERROR);
while (1)
{
askdisk("target");
remove(lastoutfname);
if (!opentarget(outfname)) continue;
while (infbytesleft)
{
if (!bytes) readsource(bytes = minimum(BUFFSIZE, infbytesleft));
if (!writetarget(bytes, NEEDNT)) break;
infbytesleft -= bytes;
bytes = 0;
}
outfsize = tell(outfh);
close(outfh);
if (!outfsize)
{
remove(outfname);
continue;
}
if (!infbytesleft) break;
incrdisk(outfext);
}
close(infh);
if (!disk) *(lastoutfname - outfname + outfext - 1) = 0;
rename(outfname, lastoutfname);
}
void bind(char *infname, char *outfname, char *lastinfname, char *infext)
{
char lastdisk = 0;
unsigned bytes;
if (!opentarget(outfname)) exit(ERROR);
while (1)
{
askdisk("source");
if (!opensource(infname, NEEDNT))
if (opensource(lastinfname, NEEDNT))
lastdisk = 1;
else
continue;
while (infbytesleft)
{
readsource(bytes = minimum(BUFFSIZE, infbytesleft));
writetarget(bytes, MUST);
infbytesleft -= bytes;
}
close(infh);
if (lastdisk) break;
incrdisk(infext);
}
close(outfh);
}
void askdisk(char *type)
{
char c;
printf("Insert disk #%hd in the %s drive and press [ENTER] - "
"Press [ESC] to quit", disk + 1, type);
fflush(stdout);
while ((c = getch()) != '\r')
if (c == '\e') /* ESC */
{
printf("\n");
exit(ABORT);
}
printf("\n");
}
void incrdisk(char *ext)
{
if (disk == 999)
{
printf("More than 1000 diskettes needed - Abort\n");
exit(ERROR);
}
sprintf(ext, "%03hd", ++disk);
}
char opensource(char *name, char condition)
{
if ((infh = open(name, O_RDONLY | O_BINARY)) < 0)
{
if (condition == MUST) printf("Error opening source file\n");
return 0;
}
lseek(infh, 0, SEEK_END);
if ((infbytesleft = tell(infh)) < 0)
{
close(infh);
printf("Error obtaining source file's size\n");
return 0;
}
lseek(infh, 0, SEEK_SET);
return 1;
}
char opentarget(char *name)
{
outfh = open(name, O_WRONLY | O_BINARY | O_TRUNC | O_CREAT
#ifdef PC
, S_IWUSR);
#else
);
#endif
if (outfh < 0)
{
printf("Error opening target file\n");
return 0;
}
return 1;
}
void readsource(unsigned bytes)
{
if (read(infh, buff, bytes) != bytes)
{
printf("Error reading source file\n");
exit(ERROR);
}
}
char writetarget(unsigned bytes, char condition)
{
if (write(outfh, buff, bytes) != bytes)
{
if (condition == NEEDNT) return 0;
printf("Error writing target file\n");
exit(ERROR);
}
return 1;
}